package cn.edu.zut.soft.graduate.core.annotation;

import cn.edu.zut.soft.basic.core.model.dao.Criteria;
import cn.edu.zut.soft.basic.core.model.dao.Page;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author cc
 * @Date 2017/2/19
 * @value 1.0
 */
public enum SimpleQueryParameterHandler implements QueryParameterHandler {

    DEFAULT;

    private static final List<Integer> rowNameLength = Arrays.asList(1, 2);

    @Override
    public void handler(Criteria criteria, Page page) throws IllegalAccessException {
        Class clazz = page.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(QueryParameter.class)) {
                QueryParameter queryParameter = field.getAnnotation(QueryParameter.class);
                if (!rowNameLength.contains(queryParameter.rowName().length)) {
                    throw new IllegalArgumentException("values length is error,rowNameLength = " + rowNameLength);
                }
                //私有访问
                field.setAccessible(true);
                Object value = field.get(page);
                //如果值为null则跳过
                if (value == null || (value instanceof Collection && ((Collection) value).isEmpty())) {
                    if (queryParameter.defaultValue() == QueryParameter.DefaultValueType.NULL) {
                        continue;
                    } else if (queryParameter.defaultValue() == QueryParameter.DefaultValueType.ZERO) {
                        value = 0;
                    } else if (queryParameter.defaultValue() == QueryParameter.DefaultValueType.NULL_SET) {
                        value = Collections.EMPTY_LIST;
                    } else if (queryParameter.defaultValue() == QueryParameter.DefaultValueType.EMPTY) {
                        value = "";
                    }
                }


                if (queryParameter.set()) {
                    if (queryParameter.equal() == QueryParameter.Type.Equal) {
                        criteria.andIn(queryParameter.rowName()[0], (List<Object>) value);
                    } else if (queryParameter.equal() == QueryParameter.Type.unEqual) {
                        criteria.andNotIn(queryParameter.rowName()[0], (List<Object>) value);
                    } else {
                        throw new IllegalArgumentException("set is error");
                    }
                } else {

                    if (queryParameter.equal() == QueryParameter.Type.Equal) {
                        criteria.andEqualTo(queryParameter.rowName()[0], value);
                    } else if (queryParameter.equal() == QueryParameter.Type.unEqual) {
                        criteria.andNotEqualTo(queryParameter.rowName()[0], value);
                    } else if (queryParameter.equal() == QueryParameter.Type.Like) {
                        criteria.andLike(queryParameter.rowName()[0], value);
                    } else if (queryParameter.equal() == QueryParameter.Type.Regex) {
                        criteria.andRegexp(queryParameter.rowName()[0], value);
                    } else if (queryParameter.equal() == QueryParameter.Type.Between) {
                        if (queryParameter.Between() == QueryParameter.BetweenType.NULL) {
                            throw new IllegalArgumentException("between is error");
                        }
                        if (queryParameter.Between() == QueryParameter.BetweenType.ROW) {
                            if (queryParameter.rowName().length != 2) {
                                throw new IllegalArgumentException("rowName length not equal 2");
                            }
                            criteria.andLessThan(queryParameter.rowName()[0], value)
                                    .andGreaterThan(queryParameter.rowName()[1], value);
                        } else if (queryParameter.Between() == QueryParameter.BetweenType.VALUE) {
                            Collection val = (Collection) value;
                            if (value instanceof Collection && (val.size() == 2)) {
                                Iterator iterator = val.iterator();
                                //由于next中的游标会向下游动所以连续使用next即可
                                criteria.andBetween(queryParameter.rowName()[0], iterator.next(), iterator.next());
                            } else {
                                throw new IllegalArgumentException("values length not equal 2");
                            }
                        }
                    }
                }
            }
        }
    }
}
